package com.uwlaser.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.uwlaser.base.PageInfo;
import com.uwlaser.base.QueryHelpMybatisPlus;
import com.uwlaser.base.impl.CommonServiceImpl;
import com.uwlaser.domain.*;
import com.uwlaser.service.PlanWorkOrderService;
import com.uwlaser.service.dto.PlanWorkOrderDto;
import com.uwlaser.service.dto.PlanWorkOrderQueryParam;
import com.uwlaser.service.mapper.*;
import com.uwlaser.utils.ConvertUtil;
import com.uwlaser.utils.PageUtil;
import com.uwlaser.utils.StringUtils;
import com.uwlaser.utils.enums.DictValueEnum;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotBlank;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author zk-Qin
* @date 2022-05-11
*/
@Service
@AllArgsConstructor
// @CacheConfig(cacheNames = PlanWorkOrderService.CACHE_KEY)
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class PlanWorkOrderServiceImpl extends CommonServiceImpl<PlanWorkOrderMapper, PlanWorkOrder> implements PlanWorkOrderService {

    // private final RedisUtils redisUtils;
    private final PlanWorkOrderMapper planWorkOrderMapper;

    private final ProductModelMapper productModelMapper;

    private final DataPassStationMapper dataPassStationMapper;

    private final DataMainMapper dataMainMapper;

    private final OrderSerialMapper orderSerialMapper;

    @Override
    public PageInfo<PlanWorkOrderDto> queryAll(PlanWorkOrderQueryParam query, Pageable pageable) {
        IPage<PlanWorkOrder> queryPage = PageUtil.toMybatisPage(pageable);
        IPage<PlanWorkOrder> page = planWorkOrderMapper.selectPage(queryPage, QueryHelpMybatisPlus.getPredicate(query));
        return ConvertUtil.convertPage(page, PlanWorkOrderDto.class);
    }

    @Override
    public List<PlanWorkOrderDto> queryAll(PlanWorkOrderQueryParam query){
        return ConvertUtil.convertList(planWorkOrderMapper.selectList(QueryHelpMybatisPlus.getPredicate(query)), PlanWorkOrderDto.class);
    }

    @Override
    public PlanWorkOrder getById(Integer id) {
        return planWorkOrderMapper.selectById(id);
    }

    @Override
    // @Cacheable(key = "'id:' + #p0")
    public PlanWorkOrderDto findById(Integer id) {
        return ConvertUtil.convert(getById(id), PlanWorkOrderDto.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(PlanWorkOrderDto resources) {
        PlanWorkOrder entity = ConvertUtil.convert(resources, PlanWorkOrder.class);
        entity.setFailQty(0);
        entity.setFinishQty(0);
        entity.setOnlineQty(0);
        entity.setScrapQty(0);
        entity.setTotalQty(0);
        entity.setUnfinishQty(0);

        PlanWorkOrder planWorkOrder = new PlanWorkOrder();
        planWorkOrder.setWorkOrderCode(entity.getWorkOrderCode());
        Integer integer = planWorkOrderMapper.selectCount(new QueryWrapper<>(planWorkOrder));
        if(integer > 0){
            throw new RuntimeException("工单编号【"+planWorkOrder.getWorkOrderCode()+"】已存在！");
        }

        return planWorkOrderMapper.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateById(PlanWorkOrderDto resources){
        PlanWorkOrder entity = ConvertUtil.convert(resources, PlanWorkOrder.class);
        int ret = planWorkOrderMapper.updateById(entity);
        PlanWorkOrder planWorkOrder = new PlanWorkOrder();
        planWorkOrder.setWorkOrderCode(entity.getWorkOrderCode());
        Integer integer = planWorkOrderMapper.selectCount(new QueryWrapper<>(planWorkOrder));
        if(integer >= 2){
            throw new RuntimeException("工单编号【"+planWorkOrder.getWorkOrderCode()+"】已存在！");
        }
        return ret;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeByIds(Set<Integer> ids){
        //同时需要删除工单序列号表中对应的记录
        List<PlanWorkOrder> planWorkOrders = planWorkOrderMapper.selectBatchIds(ids);
        //筛选工单号
        List<String> workOrderCodeIds = planWorkOrders.stream().filter(p -> p.getWorkOrderCode() != null).map(PlanWorkOrder::getWorkOrderCode).collect(Collectors.toList());
        //删除对应工单号的工单序列号记录
        orderSerialMapper.deleteByOrderCode(workOrderCodeIds);
        return planWorkOrderMapper.deleteBatchIds(ids);
    }

    @Override
    public HashMap<String, Integer> getStatusCount() {
        HashMap<String, Integer> resMap = new HashMap<>();

        List<PlanWorkOrder> list = planWorkOrderMapper.selectList(null);
        if(list == null || list.size() == 0){
            return resMap;
        }
        Map<String, List<PlanWorkOrder>> statusMap = list.stream().collect(Collectors.groupingBy(PlanWorkOrder::getOrderStatus));
        for (String key : statusMap.keySet()) {
            resMap.put(key,statusMap.get(key).size());
        }
        return resMap;
    }

    @Override
    public PageInfo<PlanWorkOrderDto> monitor(PlanWorkOrderQueryParam query, Pageable pageable) {
        PageInfo<PlanWorkOrderDto> planWorkOrderDtoPageInfo = queryAll(query, pageable);
        List<PlanWorkOrderDto> content = planWorkOrderDtoPageInfo.getContent();
        ArrayList<PlanWorkOrderDto> res = new ArrayList<>();
        if(content != null && content.size() > 0){
            for (PlanWorkOrderDto planWorkOrderDto : content) {
                if(planWorkOrderDto.getOrderStatus().equals(DictValueEnum.DATASOURCES_ISSUE.getValue())){
                    res.add(planWorkOrderDto);
                }
            }
            for (PlanWorkOrderDto planWorkOrderDto : content) {
                if(!planWorkOrderDto.getOrderStatus().equals(DictValueEnum.DATASOURCES_ISSUE.getValue())){
                    res.add(planWorkOrderDto);
                }
            }
        }
        planWorkOrderDtoPageInfo.setContent(res);
        return planWorkOrderDtoPageInfo;
    }

    @Override
    public List<Map<String, Object>> failInfo(PlanWorkOrderQueryParam query) {
        ArrayList<Map<String, Object>> resList = new ArrayList<>();

        ProductModel productModel = new ProductModel();
        productModel.setProductCode(query.getProductCode());
        ProductModel product = productModelMapper.selectOne(new QueryWrapper<>(productModel));

        if(product == null){
            return resList;
        }
        //去重判断
        HashSet<String> sfcSet = new HashSet<>();

        HashMap<String,Integer> resMap = new HashMap<>();

        DataMain dataMain = new DataMain();
        dataMain.setWorkOrderCode(query.getWorkOrderCode());
        dataMain.setResult(DictValueEnum.RESULT_NG.getValue());
        List<DataMain> dataMains = dataMainMapper.selectList(new QueryWrapper<>(dataMain));
        if(dataMains == null || dataMains.size() == 0){
            return resList;
        }
        QueryWrapper<DataPassStation> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("product_sn",dataMains.stream().map(DataMain::getProductSn).collect(Collectors.toSet()));
        List<DataPassStation> list = dataPassStationMapper.selectList(queryWrapper);
        if(list == null || list.size() == 0){
            return resList;
        }
        for (DataPassStation passStation : list) {
            if(sfcSet.add(passStation.getProductSn())){
                String ngcode = passStation.getFlawCode();
                if(StringUtils.isEmpty(ngcode)){
                    calculate(resMap,"其他");
                }else{
                    calculate(resMap,ngcode);
                }
            }
        }

        for (String key : resMap.keySet()) {
            HashMap<String, Object> map = new HashMap<>();
            map.put("name",key);
            map.put("value",resMap.get(key));
            resList.add(map);
        }
        return resList;
    }

    public void calculate(HashMap<String,Integer> resMap,String key){
        Integer value = resMap.get(key);
        if(value == null){
            resMap.put(key,1);
        }else{
            resMap.put(key,value + 1);
        }
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeById(Integer id){
        Set<Integer> set = new HashSet<>(1);
        set.add(id);
        return this.removeByIds(set);
    }

    /*
    private void delCaches(Integer id) {
        redisUtils.delByKey(CACHE_KEY + "::id:", id);
    }

    private void delCaches(Set<Integer> ids) {
        for (Integer id: ids) {
            delCaches(id);
        }
    }*/

    /*
    @Override
    public void download(List<PlanWorkOrderDto> all, HttpServletResponse response) throws IOException {
      List<Map<String, Object>> list = new ArrayList<>();
      for (PlanWorkOrderDto planWorkOrder : all) {
        Map<String,Object> map = new LinkedHashMap<>();
              map.put("工单编号", planWorkOrder.getWorkOrderCode());
              map.put("订单编号", planWorkOrder.getOrderCode());
              map.put("工单状态", planWorkOrder.getOrderStatus());
              map.put("产品型号", planWorkOrder.getProductCode());
              map.put("产品类型", planWorkOrder.getProductType());
              map.put("需求数量", planWorkOrder.getRequiredQty());
              map.put("产线编号", planWorkOrder.getLineCode());
              map.put("工段编号", planWorkOrder.getSectionCode());
              map.put("计划开始", planWorkOrder.getPlanStart());
              map.put("计划结束", planWorkOrder.getPlanEnd());
              map.put("实际开始时间", planWorkOrder.getPracticalStart());
              map.put("实际结束时间", planWorkOrder.getPracticalEnd());
              map.put("客户名称", planWorkOrder.getClientName());
              map.put("计划员", planWorkOrder.getPlanner());
              map.put("总数量(条码数量）", planWorkOrder.getTotalQty());
              map.put("完成数量（OK数量）", planWorkOrder.getFinishQty());
              map.put("失败数量（NG数量）", planWorkOrder.getFailQty());
              map.put("在线数量", planWorkOrder.getOnlineQty());
              map.put("报废数量", planWorkOrder.getScrapQty());
              map.put("未完成数量", planWorkOrder.getUnfinishQty());
              map.put("描述", planWorkOrder.getRemark());
              map.put("创建人", planWorkOrder.getCreateBy());
              map.put("创建时间", planWorkOrder.getCreateTime());
              map.put("更新人", planWorkOrder.getUpdateBy());
              map.put("更新时间", planWorkOrder.getUpdateTime());
        list.add(map);
      }
      FileUtil.downloadExcel(list, response);
    }*/
}
